#!/usr/bin/env python
# -*- coding: utf-8 -*-

# 1.列举你常见的内置函数。
"""
输入输出：
print/input
数据类型：
int/str/bool/list/tuple/dict/set/float
数学相关：
max/min/sum/abs/divmod/round/pow
进制相关：
bin/oct/hex/int
其他:
len/range/id/type/open
高级函数：
map/filter/reduce
"""

# 2.列举你常见的内置模块？
"""
json/time/datetime/os/sys/hashlib/random/shutil/getpass
"""

# 3.json序列化时，如何保留中文？
"""
import json

json.dumps(v1,ensure_ascii=False)
"""

# 4.程序设计：用户管理系统
"""
功能：
	# 1.用户注册，提示用户输入用户名和密码，然后获取当前注册时间，最后将用户名、密码、注册时间写入到文件。
	# 2.用户登录，只有三次错误机会，一旦错误则冻结账户（下次启动也无法登录，提示：用户已经冻结）。
"""
"""
import hashlib
import getpass
import sys
from datetime import datetime


def hash_md5(data):  # md5加密
    md5 = hashlib.md5('fdsajiodsaklfew90zxl.xjfieow'.encode('utf-8'))   # 加盐
    md5.update(data.encode('utf-8'))  # 数据编码utf-8
    result = md5.hexdigest()  # 加密
    return result  # 返回加密后的数据


def user_add():  # 用户注册
    print('用户注册'.center(50, '#'))
    while True:  # 循环注册
        s1 = False
        with open('user.txt', 'r', encoding='utf-8') as f1:
            user = input('请输入用户名(N/n 退出)：')
            if user.upper() == 'N':
                return
            for line in f1:
                if user in line:
                    print('用户名已存在，请重新输入！')
                    s1 = True
            if s1:  # 用户名如果存在
                continue
            pwd = getpass.getpass('请输入密码：')
        with open('user.txt', 'a', encoding='utf-8') as f2:
            user_str = (user + ',' + hash_md5(pwd) + ',' + datetime.now().strftime(
                '%Y-%m-%d %H:%M:%S') + ',' + '0' + '\n')
            f2.write(user_str)
        print('注册成功！')
        return


def login():
    print('用户登录'.center(50, '#'))
    while True:
        s1 = False
        user_list = list()  # 所有用户列表
        with open('user.txt', 'r', encoding='utf-8') as f:
            for line in f:
                ls = line.strip().split(',')
                user_dict = {'user': ls[0], 'pwd': ls[1], 'datetime': ls[2], 'flag': ls[3]}  # 单个用户信息
                user_list.append(user_dict)  # 把单个用户信息添加到列表
        user = input('请输入用户名（N/n返回）：')
        if user.upper() == 'N':
            return
        for i in user_list:     # 循环用户列表
            if user == i['user']:   # 如果用户名正确 则s1 为真
                s1 = True
            if user == i['user'] and i['flag'] == '3':  # 如果用户名正确 且flag = 3，则判定用户已锁定
                sys.exit('用户已锁定！')
        if not s1:  # 如果s1 为假，则提示用户，用户名不存在。
            print('用户不存在，请重新输入！')
            continue
        pwd = getpass.getpass('请输入密码：')
        for i in user_list:     # 循环所有用户
            if user == i['user'] and hash_md5(pwd) != i['pwd']:   # 如果用户名在文件中，且密码不正确
                print('用户名或密码错误！你还有%s次错误机会。' % (2 - int(i['flag']),))
                i['flag'] = str(int(i['flag']) + 1)     # 所在文件的flag+1，并且将文件重新写一次。
                with open('user.txt', 'w', encoding='utf-8') as f:
                    for line in user_list:
                        ls = list()
                        for val in line.values():
                            ls.append(val)
                        f.write(','.join(ls) + '\n')
                break
            if user == i['user'] and hash_md5(pwd) == i['pwd']:
                sys.exit('登录成功！')


while True:
    print('用户登录'.center(50, '#'))
    print('1.用户注册')
    print('2.用户登录')
    num = input('请输入序号（N/n退出）：')
    if num.upper() == 'N':
        sys.exit('谢谢使用！')
    if num == '1':
        user_add()
    elif num == '2':
        login()
    else:
        print('输入有误，请重新输入！')
        continue
"""

# 5.有如下文件，请通过分页的形式将数据展示出来。【文件非常小】
"""
# with open('pager.txt', 'r', encoding='utf-8') as f:
#     values = list()
#     key = f.readline().strip().split('|')
#     for line in f:
#         values.append(line.strip().split('|'))
# while True:
#     value_total = len(values)
#     pager_count = 5
#     pager_max, a = divmod(value_total, pager_count)
#     if a > 0:
#         pager_max += 1
#     pager = input('请输入你要查看的页码（N/n 退出）：')
#     if pager.upper() == 'N':
#         break
#     if not pager.isdecimal():
#         print('输入有误，重新输入！')
#         continue
#     if int(pager) < 1 or int(pager) > pager_max:
#         print('页码不合法，请输入%s-%s页' % (1, pager_max))
#     else:
#         start = (int(pager) - 1) * pager_count
#         end = int(pager) * pager_count
#         data = values[start:end]
#         print(' '.join(key))
#         for i in data:
#             print(' '.join(i))
"""

# 6.有如下文件，请通过分页的形式将数据展示出来。【文件非常大】
"""
# with open('pager.txt', 'r', encoding='utf-8') as f:
#     values = list()
#     key = f.readline().strip().split('|')
#     for line in f:
#         values.append(line.strip().split('|'))
# while True:
#     value_total = len(values)
#     pager_count = 5
#     pager_max, a = divmod(value_total, pager_count)
#     if a > 0:
#         pager_max += 1
#     pager = input('请输入你要查看的页码（N/n 退出）：')
#     if pager.upper() == 'N':
#         break
#     if not pager.isdecimal():
#         print('输入有误，重新输入！')
#         continue
#     if int(pager) < 1 or int(pager) > pager_max:
#         print('页码不合法，请输入%s-%s页' % (1, pager_max))
#     else:
#         start = (int(pager) - 1) * pager_count
#         end = int(pager) * pager_count
#         data = values[start:end]
#         print(' '.join(key))
#         for i in data:
#             print(' '.join(i))
"""

# 7.程序设计：购物车
"""
有如下商品列表 GOODS_LIST，用户可以选择进行购买商品并加入到购物车 SHOPPING_CAR 中且可以选择要购买数量，
购买完成之后将购买的所有商品写入到文件中【文件格式为：年_月_日.txt】。
注意：重复购买同一件商品时，只更改购物车中的数量。
"""

"""
import sys
from datetime import datetime

# 购物车
SHOPPING_CAR = list()

# 商品列表
GOODS_LIST = [
    {'id': 1, 'title': '飞机', 'price': 1000},
    {'id': 3, 'title': '大炮', 'price': 1000},
    {'id': 8, 'title': '迫击炮', 'price': 1000},
    {'id': 9, 'title': '手枪', 'price': 1000},
]


def goods():
    print('欢迎光临军火武器商城'.center(50, '#'))
    while True:
        print('序号', '商品名称', '价格')
        for i in GOODS_LIST:
            values_list = list()
            for value in i.values():
                values_list.append(value)
            print('%s %s %s' % (
                values_list[0],
                values_list[1],
                values_list[2]))
        num = input('请选择序号（N/n退出）：')
        if num.upper() == 'N':
            return
        if not num.isdecimal():
            print('输入有误，请重新输入')
            continue
        flag = False
        for i in GOODS_LIST:
            if int(num) == i['id']:
                flag = True
                break
        if not flag:
            print('商品不存在，请重新输入')
            continue
        else:
            while True:
                count = input('你要购买的数量：')
                if not count.isdecimal():
                    print('输入有误，请重新输入')
                    continue
                else:
                    flag1 = False
                    for i in SHOPPING_CAR:
                        if int(num) == i['id']:
                            flag1 = True
                            break
                    if flag1:
                        i['count'] += int(count)
                        i['price'] = i['unit'] * i['count']
                    else:
                        for i in GOODS_LIST:
                            temp_dict = {'count': int(count), 'unit': None}
                            for k, v in i.items():
                                temp_dict[k] = v
                            if int(num) == temp_dict['id']:
                                temp_dict['unit'] = temp_dict['price']
                                temp_dict['price'] *= int(count)
                                SHOPPING_CAR.append(temp_dict)
                # print(SHOPPING_CAR)
                break


def shopping():
    print('购物车'.center(50, '#'))
    total = 0
    print('商品名称', '单价', '数量', '总价')
    for i in SHOPPING_CAR:
        print(i['title'], i['unit'], i['count'], i['price'])
        total += i['price']
    print('合计%s' % total)
    while True:
        pay = input('是否购买？（Y/N):')
        if pay.upper() == 'N':
            sys.exit('谢谢使用！欢迎再次光临！')
        if pay.upper() == 'Y':
            pay_datetime = datetime.now().strftime('%Y-%m-%d_%H%M%S')
            with open(pay_datetime + '.txt', 'w', encoding='utf-8') as f:
                f.write('数量' + ',' +
                        '单价' + ',' +
                        'id' + ',' +
                        '商品名称' + ',' +
                        '总价' + '\n')
                for i in SHOPPING_CAR:
                    val = list()
                    for v in i.values():
                        val.append(str(v))
                    f.write(','.join(val) + '\n')
            print('支付成功')
            break
        else:
            print('输入有误，请重新输入')
            continue


goods()
shopping()
"""

# 8.程序设计：沙河商城
"""
# 功能：
# 	1.用户注册，提示用户输入用户名和密码，然后获取当前注册时间，最后将用户名、密码、注册时间写入到文件。
# 	2.用户登录，只有三次错误机会，一旦错误则冻结账户（下次启动也无法登录，提示：用户已经冻结）。
# 	3.商品浏览，分页显示商品（小文件）； 用户可以选择商品且可以选择数量然后加入购物车（在全局变量操作），
# 	  不再购买之后，需要讲购物车信息写入到文件，文件要写入到指定目录：
# 		shopping_car(文件夹)
# 			- 用户名A(文件夹)
# 				2019-11-11-09-59.txt
# 				2019-11-12-11-56.txt
# 				2019-12-11-11-47.txt
# 			- 用户B(文件夹)
# 				2019-11-11-11-11.txt
# 				2019-11-12-11-15.txt
# 				2019-12-11-11-22.txt
# 	  注意：重复购买同一件商品时，只更改购物车中的数量。
# 	4.我的购物车，查看用户所有的购物车记录，即：找到shopping_car目录下当前用户所有的购买信息，并显示：
# 		2019-11-11-09-59
# 			飞机|1000|10个
# 			大炮|2000|3个
# 		2019-11-12-11-56.txt
# 			迫击炮|10000|10个
# 			手枪|123|3个
# 
# 	5.用户未登录的情况下，如果访问 商品流程 、我的购物车 时，提示登录之后才能访问，让用户先去选择登录（装饰器实现）。
"""

import hashlib
import getpass
import sys
import os
from datetime import datetime

SHOPPING_CAR = list()
USERNAME = None


def hash_md5(data):  # md5加密
    md5 = hashlib.md5('fdsajiodsaklfew90zxl.xjfieow'.encode('utf-8'))  # 加盐
    md5.update(data.encode('utf-8'))  # 数据编码utf-8
    result = md5.hexdigest()  # 加密
    return result  # 返回加密后的数据


def func1(func):
    def inner(*args, **kwargs):
        if USERNAME:
            func(*args, **kwargs)
        else:
            login()
        return

    return inner


def user_add():  # 用户注册
    print('用户注册'.center(50, '#'))
    while True:  # 循环注册
        s1 = False
        with open('user.txt', 'r', encoding='utf-8') as f1:
            user = input('请输入用户名(N/n 退出)：')
            if user.upper() == 'N':
                return
            for line in f1:
                if user in line:
                    print('用户名已存在，请重新输入！')
                    s1 = True
            if s1:  # 用户名如果存在
                continue
            pwd = getpass.getpass('请输入密码：')
        with open('user.txt', 'a', encoding='utf-8') as f2:
            user_str = (user + ',' + hash_md5(pwd) + ',' + datetime.now().strftime(
                '%Y-%m-%d %H:%M:%S') + ',' + '0' + '\n')
            f2.write(user_str)
            os.makedirs(r'G:\code\project1\shopping_car\%s' % user)
        print('注册成功！')
        return


def login():
    print('用户登录'.center(50, '#'))
    while True:
        s1 = False
        user_list = list()  # 所有用户列表
        with open('user.txt', 'r', encoding='utf-8') as f:
            for line in f:
                ls = line.strip().split(',')
                user_dict = {'user': ls[0], 'pwd': ls[1], 'datetime': ls[2], 'flag': ls[3]}  # 单个用户信息
                user_list.append(user_dict)  # 把单个用户信息添加到列表
        user = input('请输入用户名（N/n返回）：')
        if user.upper() == 'N':
            return
        for i in user_list:  # 循环用户列表
            if user == i['user']:  # 如果用户名正确 则s1 为真
                s1 = True
            if user == i['user'] and i['flag'] == '3':  # 如果用户名正确 且flag = 3，则判定用户已锁定
                sys.exit('用户已锁定！')
        if not s1:  # 如果s1 为假，则提示用户，用户名不存在。
            print('用户不存在，请重新输入！')
            continue
        pwd = getpass.getpass('请输入密码：')
        for i in user_list:  # 循环所有用户
            if user == i['user'] and hash_md5(pwd) != i['pwd']:  # 如果用户名在文件中，且密码不正确
                print('用户名或密码错误！你还有%s次错误机会。' % (2 - int(i['flag']),))
                i['flag'] = str(int(i['flag']) + 1)  # 所在文件的flag+1，并且将文件重新写一次。
                with open('user.txt', 'w', encoding='utf-8') as f:
                    for line in user_list:
                        ls = list()
                        for val in line.values():
                            ls.append(val)
                        f.write(','.join(ls) + '\n')
                break
            if user == i['user'] and hash_md5(pwd) == i['pwd']:
                print('登录成功！')
                global USERNAME
                USERNAME = user
                return


@func1
def goods(user):
    print('商品浏览'.center(50, '#'))
    while True:
        with open('goods.txt', 'r', encoding='utf-8') as f:
            keys = f.readline().strip().split('|')
            values = list()
            count = 1
            for i in f:
                value_dict = dict()
                value = i.strip().split('|')
                value_dict['id'] = count
                value_dict[keys[0]] = value[0]
                value_dict[keys[1]] = value[1]
                value_dict[keys[2]] = value[2]
                count += 1
                values.append(value_dict)
        page_count = len(values)
        page = 5
        page_max, a = divmod(page_count, page)
        if a > 0:
            page_max += 1
        while True:
            page_num = input('请输入页码(N退出)：')
            if page_num.upper() == 'N':
                break
            if not page_num.isdecimal():
                print('输入有误，请重新输入')
                continue
            if int(page_num) < 1 or int(page_num) > page_max:
                print('页码不合法，请输入1 - %s' % page_max)
                continue
            star = (int(page_num) - 1) * page
            end = int(page_num) * page
            print(' '.join(keys))
            for value in values[star:end]:
                print(' '.join(value.values()))
        num = input('请选择商品序号（N/n退出）：')
        if num.upper() == 'N':
            shopping_path = r'G:\code\project1\shopping_car\%s\%s' % (user, datetime.now().strftime('%Y-%m-%d-%H-%M'))
            with open(shopping_path + '.txt', 'w', encoding='utf-8') as f:
                total = 0
                f.write('数量' + '|' +
                        '单价' + '|' +
                        'id' + '|' +
                        '商品名称' + '|' +
                        '总价' + '\n')
                for i in SHOPPING_CAR:
                    val = list()
                    for v in i.values():
                        val.append(str(v))
                    f.write('|'.join(val) + '\n')
                    total += int(val[-1])
                f.write('合计'+'|'+str(total))
            return
        if not num.isdecimal():
            print('输入有误，请重新输入')
            continue
        flag = False
        for i in values:
            if num == i['id']:
                flag = True
                break
        if not flag:
            print('商品不存在，请重新输入')
            continue
        else:
            while True:
                count = input('你要购买的数量：')
                if not count.isdecimal():
                    print('输入有误，请重新输入')
                    continue
                else:
                    flag1 = False
                    for i in SHOPPING_CAR:
                        if int(num) == i['id']:
                            flag1 = True
                            break
                    if flag1:
                        i['数量'] += int(count)
                        i['价格'] = i['单价'] * i['数量']
                    else:
                        for i in values:
                            temp_dict = {'数量': int(count), '单价': None}
                            for k, v in i.items():
                                temp_dict[k] = v
                            if num == temp_dict['id']:
                                temp_dict['单价'] = temp_dict['价格']
                                temp_dict['价格'] = int(temp_dict['价格']) * int(count)
                                SHOPPING_CAR.append(temp_dict)
                break


@func1
def shopping(user):
    print('购物车'.center(50, '#'))
    path_list = os.listdir(r'G:\code\project1\shopping_car\%s' % user)
    if path_list:
        for path in path_list:
            with open(r'G:\code\project1\shopping_car\%s\%s' % (user, path), 'r', encoding='utf-8') as f:
                print(path)
                print(' '.join(f.readline().strip().split('|')))
                for line in f:
                    print(' '.join(line.strip().split('|')))
    else:
        print('购物车是空的！')
    while True:
        back = input('N返回主页:')
        if back.upper() == 'N':
            return
        else:
            print('输入有误！')


def home_page():
    while True:
        print('用户登录'.center(50, '#'))
        print('1.用户注册')
        print('2.用户登录')
        print('3.商品浏览')
        print('4.购物车')
        num = input('请输入序号（N/n退出）：')
        if num.upper() == 'N':
            sys.exit('谢谢使用！')
        if num == '1':
            user_add()
        elif num == '2':
            login()
        elif num == '3':
            goods(USERNAME)
        elif num == '4':
            shopping(USERNAME)
        else:
            print('输入有误，请重新输入！')
            continue


home_page()
